package com.sdhs.common.utils.poi;

import cn.hutool.core.io.resource.ClassPathResource;
import cn.hutool.core.io.resource.Resource;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;

@Slf4j
public class TemplateExcelUtils {

    /***
     * @Author add
     * @Description TODO excel导出
     * @MothodName export
     * @Date 2025/04/03 11:28
     * @param templateName 模板名称
     * @param exportName 导出excel名称
     * @param data 导出数据
     * @param response
     * @Return
     */
    public static <T> void export(String templateName, String exportName, Map<String, T> data, HttpServletResponse response) throws Exception {
        // 加载resource下的Excel模板
        Resource res = new ClassPathResource("template/" + templateName);
        InputStream inputStream = res.getStream();

        Workbook workbook = new XSSFWorkbook(inputStream);
        Sheet sheet = workbook.getSheetAt(0);
/*        // 冻结前两行
        sheet.createFreezePane(0, 2);*/

        // 首先处理非List类型的字段（如projectName等）
        for (Row row : sheet) {
            for (Cell cell : row) {
                if (cell.getCellType() == CellType.STRING) {
                    String value = cell.getStringCellValue();
                    if (value.startsWith("${") && value.endsWith("}")) {
                        String key = value.substring(2, value.length() - 1);
                        // 检查是否是直接字段（不包含点号）
                        if (!key.contains(".") && data.containsKey(key)) {
                            Object fieldValue = data.get(key);
                            if (fieldValue != null) {
                                cell.setCellValue(fieldValue.toString());
                            }
                        }
                    }
                }
            }
        }

        List<Object> objectList = new ArrayList<>();
        for (Map.Entry<String, T> stringObjectEntry : data.entrySet()) {
            if(stringObjectEntry.getValue() instanceof List<?>) {
                objectList = (List<Object>) stringObjectEntry.getValue();
            }
        }

        if(!CollectionUtils.isEmpty(objectList)) {
            for (int i = 0; i < objectList.size(); i++) {
                Object object = objectList.get(i);
                //Row表示excel中的一行数据，这句话的含义是获取最后一行excel(有数据的)
                XSSFRow modelRow = (XSSFRow) sheet.getRow(sheet.getLastRowNum());
                //创建一个新的行
                XSSFRow newRow = (XSSFRow) sheet.createRow(sheet.getLastRowNum() + 1);
                //复制模板行到新的行
                newRow.copyRowFrom(modelRow, new CellCopyPolicy());
                for (Cell cell : modelRow) {//遍历单元格Cell表示单元格
                    //获取单元格的值
                    String value = cell.getStringCellValue();
                    if (value.startsWith("${") && value.endsWith("}")) {
                        //截取字符串获取%%中间的内容
                        value = value.substring(2, value.length() - 1);
                        //replaceNull属性表示如果object中的值为null是否将"”替换到单元格中，如果替换，则显示空白，如果不替换，则显示模板内容
                        if (StringUtils.isNoneBlank(value)) {
                            //获取object中的属性值，并赋值到单元格中
                            cell.setCellValue(parseTemplate(value, object));
                        }
                    }
                }
            }
        }
        //删除模板行
        sheet.removeRow(sheet.getRow(sheet.getLastRowNum()));

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        String fileName = simpleDateFormat.format(new Date()) + "_" + exportName;
        //设置文件类型
        response.setContentType("application/vnd.ms-excel;charset=UTF-8");
        //设置编码格式
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");

        OutputStream outputStream = response.getOutputStream();
        workbook.write(outputStream);
        outputStream.close();
        workbook.close();
    }

    private static String parseTemplate(String template, Object obj) {
        try {
            if(!template.contains(".")) {
                JSONObject jsonObject = (JSONObject) JSONObject.toJSON(obj);
                return jsonObject.getString(template);
            }
            // 判断.出现次数
            int countNum = countOccurrences(template, ".");
            if(countNum > 1){
                throw new Exception("模版标签错误!");
            }
            Pattern pattern = Pattern.compile("\\.");
            String[] keySplitList = pattern.split(template);
            template = keySplitList[1];

            JSONObject jsonObject = (JSONObject) JSONObject.toJSON(obj);
            return jsonObject.getString(template);
        }catch (Exception e) {
            log.error("属性没有找到!", e);
        }
        return "";
    }

    private static int countOccurrences(String str, String subStr) {
        int count = 0;
        Pattern pattern = Pattern.compile("\\.");
        String[] parts = pattern.split(str);
        count = parts.length - 1;
        return count;
    }

}
